package com.utils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import cn.hutool.core.bean.BeanUtil;

import com.baomidou.mybatisplus.mapper.Wrapper;

/**
 * Mybatis-Plus工具类
 * 提供Mybatis-Plus相关的常用工具方法，帮助进行SQL查询条件的生成。
 *
 * @author team10
 */
public class MPUtil {
	public static final char UNDERLINE = '_'; // 下划线常量

	// mybatis plus allEQ 表达式转换，带前缀
	public static Map allEQMapPre(Object bean, String pre) {
		Map<String, Object> map = BeanUtil.beanToMap(bean);
		return camelToUnderlineMap(map, pre);
	}

	// mybatis plus allEQ 表达式转换，默认无前缀
	public static Map allEQMap(Object bean) {
		Map<String, Object> map = BeanUtil.beanToMap(bean);
		return camelToUnderlineMap(map, "");
	}

	// mybatis plus allLike 表达式转换，带前缀
	public static Wrapper allLikePre(Wrapper wrapper, Object bean, String pre) {
		Map<String, Object> map = BeanUtil.beanToMap(bean);
		Map result = camelToUnderlineMap(map, pre);
		return genLike(wrapper, result);
	}

	// mybatis plus allLike 表达式转换，默认无前缀
	public static Wrapper allLike(Wrapper wrapper, Object bean) {
		Map result = BeanUtil.beanToMap(bean, true, true);
		return genLike(wrapper, result);
	}

	// 生成like查询条件
	public static Wrapper genLike(Wrapper wrapper, Map param) {
		Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
		int i = 0;
		while (it.hasNext()) {
			if (i > 0) wrapper.and(); // 添加and连接符
			Map.Entry<String, Object> entry = it.next();
			String key = entry.getKey();
			String value = (String) entry.getValue();
			wrapper.like(key, value); // 添加like条件
			i++;
		}
		return wrapper;
	}

	// like 或者等于条件，默认无前缀
	public static Wrapper likeOrEq(Wrapper wrapper, Object bean) {
		Map result = BeanUtil.beanToMap(bean, true, true);
		return genLikeOrEq(wrapper, result);
	}

	// 生成like 或 eq 查询条件
	public static Wrapper genLikeOrEq(Wrapper wrapper, Map param) {
		Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
		int i = 0;
		while (it.hasNext()) {
			if (i > 0) wrapper.and(); // 添加and连接符
			Map.Entry<String, Object> entry = it.next();
			String key = entry.getKey();
			if (entry.getValue().toString().contains("%")) {
				wrapper.like(key, entry.getValue().toString().replace("%", ""));
			} else {
				wrapper.eq(key, entry.getValue());
			}
			i++;
		}
		return wrapper;
	}

	// allEq 等于条件，默认无前缀
	public static Wrapper allEq(Wrapper wrapper, Object bean) {
		Map result = BeanUtil.beanToMap(bean, true, true);
		return genEq(wrapper, result);
	}

	// 生成eq查询条件
	public static Wrapper genEq(Wrapper wrapper, Map param) {
		Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
		int i = 0;
		while (it.hasNext()) {
			if (i > 0) wrapper.and(); // 添加and连接符
			Map.Entry<String, Object> entry = it.next();
			String key = entry.getKey();
			wrapper.eq(key, entry.getValue()); // 添加eq条件
			i++;
		}
		return wrapper;
	}

	// between条件，处理时间范围等情况
	public static Wrapper between(Wrapper wrapper, Map<String, Object> params) {
		for (String key : params.keySet()) {
			String columnName = "";
			if (key.endsWith("_start")) {
				columnName = key.substring(0, key.indexOf("_start"));
				if (StringUtils.isNotBlank(params.get(key).toString())) {
					wrapper.ge(columnName, params.get(key)); // ge 大于等于
				}
			}
			if (key.endsWith("_end")) {
				columnName = key.substring(0, key.indexOf("_end"));
				if (StringUtils.isNotBlank(params.get(key).toString())) {
					wrapper.le(columnName, params.get(key)); // le 小于等于
				}
			}
		}
		return wrapper;
	}

	// 排序条件
	public static Wrapper sort(Wrapper wrapper, Map<String, Object> params) {
		String order = "";
		if (params.get("order") != null && StringUtils.isNotBlank(params.get("order").toString())) {
			order = params.get("order").toString();
		}
		if (params.get("sort") != null && StringUtils.isNotBlank(params.get("sort").toString())) {
			if (order.equalsIgnoreCase("desc")) {
				wrapper.orderDesc(Arrays.asList(params.get("sort"))); // 降序排序
			} else {
				wrapper.orderAsc(Arrays.asList(params.get("sort"))); // 升序排序
			}
		}
		return wrapper;
	}

	/**
	 * 驼峰格式字符串转换为下划线格式字符串
	 *
	 * @param param 驼峰格式字符串
	 * @return 下划线格式字符串
	 */
	public static String camelToUnderline(String param) {
		if (param == null || "".equals(param.trim())) {
			return "";
		}
		int len = param.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c = param.charAt(i);
			if (Character.isUpperCase(c)) {
				sb.append(UNDERLINE);
				sb.append(Character.toLowerCase(c)); // 转换为小写并添加下划线
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	public static void main(String[] ages) {
		System.out.println(camelToUnderline("ABCddfANM"));
	}

	/**
	 * 将Map中的驼峰格式键名转换为下划线格式，并可以带上前缀
	 *
	 * @param param Map对象
	 * @param pre 前缀
	 * @return 转换后的Map
	 */
	public static Map camelToUnderlineMap(Map param, String pre) {

		Map<String, Object> newMap = new HashMap<String, Object>();
		Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<String, Object> entry = it.next();
			String key = entry.getKey();
			String newKey = camelToUnderline(key); // 转换键名为下划线格式
			if (pre.endsWith(".")) {
				newMap.put(pre + newKey, entry.getValue()); // 拼接前缀
			} else if (StringUtils.isEmpty(pre)) {
				newMap.put(newKey, entry.getValue());
			} else {
				newMap.put(pre + "." + newKey, entry.getValue()); // 拼接前缀
			}
		}
		return newMap;
	}
}
